home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / gfx / ifx / LoadGifAnim.lha / LoadGifAnim.Ifx < prev   
Text File  |  1999-02-24  |  17KB  |  772 lines

  1. /*
  2. ** LoadGifAnim.Ifx
  3. ** $ver:   1.0, 17 Feb 1999
  4. ** by Bryan K. Williams, icar@evilgeniuses.org
  5. ** © CrystalWorks
  6. ** http://www.evilgeniuses.org/
  7. **
  8. ** Send bug reports to GifBug@evilgeniuses.org
  9. ** Find the latest version at <http://www.evilgenius.org/crystalworks/Amiga/>
  10. **
  11. ** Don't laugh too hard at my overuse of DO/END pairs :-)
  12. ** 
  13. ** History
  14. ** 1.0, 17 Feb 1999:  Fixed stupid error on anims that had a Local Color Map
  15. **    and transparency.  This was the only anim situation I was unable to test
  16. **    because I couldn't find a gif that did this.  The result was corrupt gifs
  17. **    that would cause IFX to guru.
  18. ** 0.99, 15 Feb 1999: Added support for anims that do not supply a complete
  19. **    background in the first frame. I think I've covered most, if not all,
  20. **    gif anim possibilities.  I know someone will prove me wrong on this :-)
  21. ** 0.15, 14 Feb 1999: Noticed bug in handling of local color tables and 
  22. **    transparency.  Should work now, but I'm unable to find a gif to test it.
  23. **    Added some user friendliness :^)
  24. ** 0.12, 10 Feb 1999: A partial rewrite in order implement Anim Busting.  Also
  25. **    to better handle some gifs.
  26. ** 0.10, 05 Feb 1999: Now properly handles gifs with a Disposal method of 2 (Restore
  27. **    to background color).  Not done in the best way, but it works
  28. ** 0.9, 01 Feb 1999: Properly handles gifs with a transparent color that's duplicated
  29. **    within the normal palette (i.e. has a black color, but also uses a second, equal
  30. **    black for the transparent color)
  31. ** 0.8, 31 Jan 1999: Added ability to work with some (most?) delta frame gif anims.
  32. **    Still needs to check the GCL's Disposal Method for frames to decide what to do
  33. **    with them.
  34. ** 0.7, 26 Jan 1999: Working with full frame images
  35. */
  36. /*
  37. ** Add rexxsupport.library if it isn't already open. 
  38. */
  39. if ~show('L',"rexxsupport.library") then 
  40.    if ~addlib('rexxsupport.library',0,-30,0) then exit 10
  41.  
  42. options results
  43.  
  44. Temp = Pragma('i')
  45. TempDir = "T:"
  46.  
  47. Image. = ""
  48. debug=1
  49.  
  50. loadpath=""
  51. SavePath=""
  52. 'getprefs' 'loadpath'
  53. if rc=0 then
  54. do
  55.    Loadpath = result
  56. end
  57.  
  58. 'Getprefs' 'Savepath'
  59. if rc=0 then
  60. do
  61.    Savepath = result
  62. end
  63.  
  64. /*
  65. ** Previous load info
  66. **
  67. ** PreviousName and PreviousFrame are to clips set
  68. ** after a gif frame has been loaded.  If the same image
  69. ** is used, the script will advance to the next frame as 
  70. ** the default
  71. **
  72. ** If the same gif has been selected, PreviousSplitInfo will have various
  73. ** info about the anim, rather than parse through it again.
  74. */
  75.  
  76. PreviousName=GetClip('GIFLoaderPrevName')
  77. if PreviousName~="" then
  78. do
  79.    LoadPath = GetPath(previousName)
  80. end   
  81. PreviousFrame=GetClip('GIFLoaderPrevFrame')
  82. result = GetClip('GIFSaveDir')
  83. if result~="" then
  84. do
  85.    SavePath = result
  86. end
  87.  
  88. if PreviousFrame="" | ~datatype(PreviousFrame,'W') then 
  89. do
  90.    PreviousFrame=1
  91. end 
  92.  
  93. FullFrameFlag = 1
  94. TranspFlag = 0
  95.  
  96. 'Getmain'
  97. if rc=0 then
  98. do
  99.    'requestresponse' '"Do you wish to overwrite the current buffer?"'
  100.    if rc~=0 then exit
  101. end
  102.  
  103. 'RequestFile' '"Load Gif Anim"' 'Path' LoadPath 'Pattern *.gif'
  104. if rc~=0 then exit
  105. filename = result
  106.  
  107. if upper(right(filename,4))=".GIF" then
  108. do
  109.    savefile = getfile(filename)
  110.    savefile = left(savefile,length(savefile)-4)
  111. end
  112. else
  113. do
  114.    savefile=getfile(filename)
  115. end
  116.  
  117. if filename=PreviousName then
  118. do
  119.    PreviousFrame=PreviousFrame+1
  120. end
  121. else
  122. do
  123.    PreviousFrame=1
  124. end
  125.  
  126. if ~open('in',filename,'r') then 
  127. do
  128.    'RequestNotify' 'Unable to open file' Filename
  129.    exit
  130. end
  131.  
  132. header=""
  133.  
  134. Call CheckId()
  135. Call GetLSD()
  136.  
  137. /*
  138. ** read global color table (maybe)
  139. ** 3 bytes * 2^bitplates 
  140. */
  141.  
  142. gct=""
  143. if Globalcolor=1 then 
  144. do
  145.    GCT = GetCT(sizeotable)
  146. end
  147.  
  148. Call CountFrames()
  149.  
  150. BackgroundFlag = CheckBackground()
  151. if BackgroundFlag=1 then FullFrameFlag=0
  152.  
  153. if framecount<=0 then 
  154. do
  155.    'Requestnotify' '"Gif has no images! (How Odd)"'
  156.    call quit()
  157. end
  158.  
  159. /* if framecount = 1 then just load the damn thing! */
  160. if framecount=1 then
  161. do
  162.    'LoadBuffer' '"'filename'"'
  163.    call quit()
  164. end
  165.  
  166. /*
  167. **    BustAnim : This variable decides if we're going to
  168. ** just break up the entire Anim (1) or load just one
  169. ** frame (0)
  170. **
  171. **    Accuracy : This variable decides the method of loading
  172. ** the gif.  Some gifs are anims in which each frame is the 
  173. ** entire frame.  For these, you want to do a quick load.
  174. ** Others are delta frames, they only have what's different
  175. ** between each frame of animation.  These are more complex
  176. ** and require some processing.
  177. **
  178. **    This section tries to figure out what kind of anim the
  179. ** gif is.  If it can't figure it out, it asks you if you want
  180. ** to try a QUICK load.  Try it and see.  If it doesn't work, 
  181. ** go back and do an accurate load.
  182. */
  183.  
  184. BustAnim=0  /* Don't Bust Anim */
  185. Accuracy=0  /* Quick load */
  186. 'requestresponse' '"Do you wish to bust this anim?"'
  187. if rc=0 then 
  188. do
  189.    BustAnim=1
  190.    Accuracy=1
  191.    'requestfile' 'DIRONLY' 'Path' Savepath 'Title "Save file directory"'
  192.    if rc~=0 then 
  193.    do
  194.       call quit()
  195.    end
  196.    Savepath = result
  197.    if right(savepath,1)~='/' & right(savepath,1)~=':' then
  198.    do
  199.       savepath = savepath||'/'
  200.    end
  201. end
  202.  
  203. 'lockgui'
  204. 'lockinput'
  205.  
  206. if BustAnim=0 then
  207. do
  208.    reqFrame = REquestFrame()
  209.  
  210. /* make sure a frame was selected */
  211.    if ~datatype(ReqFrame,'W') then
  212.    do
  213.       call quit()
  214.    end
  215. end
  216. else
  217. do
  218.    ReqFrame = FrameCount
  219. end
  220.  
  221. if FullFrameFlag=1 then
  222. do
  223.    if TranspFlag=0 then
  224.    do
  225.       Accuracy=0
  226.    end
  227.    else
  228.    do
  229.       'requestresponse' '"Do you wish to try to load QUICK?"'
  230.       if rc=0 then
  231.       do
  232.          Accuracy=0
  233.       end
  234.       else
  235.       do
  236.          Accuracy=1
  237.       end
  238.    end
  239. end
  240. else
  241. do
  242.    Accuracy=1
  243. end
  244.  
  245.  
  246. if Accuracy=0 & BustAnim=0 then
  247. do
  248.    call SaveFrame(ReqFrame)
  249.    'LoadBuffer' '"'TempDir||Temp'.gif"'
  250.    call delete(Tempdir||Temp'.gif')
  251. end   
  252. else
  253. /* We're doing a Accurate load, and may be busting an anim */
  254. Do count = 1 to ReqFrame
  255.    Call CreateImage(count)
  256. end
  257.  
  258. call quit()
  259. exit
  260.  
  261. **************************
  262. CheckId:
  263.  
  264. /* 
  265. ** read identifier
  266. ** 6 bytes
  267. */
  268.  
  269. line = readch('in',6)
  270. if line ~="GIF89a"  & line ~="GIF87a" then
  271. do
  272.    RequestNotify '"'filename' is not an gif."'
  273.    call quit()
  274. end
  275. header=header||line
  276. return
  277.  
  278. **************************
  279. GetLSD:
  280.  
  281. /* 
  282. ** LSD - Logical Screen Descriptor (no, not a drug)
  283. ** reads the logical screen descriptor, 7 bytes
  284. **
  285. ** Ok, a lot of this stuff can probably be taken out, but
  286. ** it helped in making the dang thing :-)
  287. */
  288.  
  289. LSD=readch('in',7)
  290. /* Screen width/height, which may or may not be image width/height */
  291. width = c2d(reverse(substr(lsd,1,2)))
  292. height = c2d(reverse(substr(lsd,3,2)))
  293.  
  294. stuff = c2b(substr(lsd,5,1))
  295. GlobalColor = c2d(b2c(substr(stuff,1,1)))
  296. colorRes = c2d(b2c(substr(stuff,2,3))) +1
  297. TotalPalette = (2**colorres)**3
  298. sortflag = c2d(b2c(substr(stuff,5,1)))
  299. sizeotable = c2d(b2c(substr(stuff,6,3)))+1
  300. backgrd = c2d(substr(lsd,6,1))
  301.  
  302. ratio = c2d(substr(lsd,7,1))
  303. if ratio=0 then ratio=1
  304.  
  305. header=header || lsd
  306.  
  307. Return
  308.  
  309. /***************************/
  310.  
  311. GetCT: procedure
  312. /*
  313. ** Reads a Color Table
  314. */
  315. parse arg TableSize
  316. return(readch('in',3*(2**TableSize)))
  317.  
  318. /***************************/
  319.  
  320. CountFrames:
  321.  
  322. /*
  323. ** This subroutine will count the number of frames in the image
  324. ** and also figure out the start and end position of each frame
  325. ** for quicker loading
  326. */
  327.  
  328. framecount = 0
  329. /* get current position, so we can return */
  330.  
  331. do while ~eof('in')
  332.    nx = readch('in',1)
  333.  
  334.    framecount=framecount+1
  335.  
  336.    do while nx~="2C"x & Nx~='3B'x
  337.       if nx = '21'x then
  338.       do
  339.          if skipBlocks()=0 then 
  340.          do
  341.             framecount=framecount-1
  342.             return
  343.          end
  344.       end
  345.       else 
  346.       do
  347.          'requestnotify' '"Somethings very wrong.  Hex character 'c2x(nx)' found.  Exiting..."'
  348.          call quit()
  349.       end
  350.  
  351.       nx = readch('in',1)
  352.    end
  353.  
  354. /* found all the frames */
  355.    if nx='3b'x then 
  356.    do
  357.       framecount= framecount-1
  358.       return
  359.    end
  360.  
  361. /* Finally found an image */
  362.  
  363.    Image.framecount.start=seek('in',0)-1
  364.  
  365.    code.=""
  366.    codecount = 0
  367.    codehead = nx||readch('in',9)
  368.  
  369.    Image.Framecount.left   = c2d(reverse(substr(codehead,2,2)))
  370.    Image.Framecount.top    = c2d(reverse(substr(codehead,4,2)))
  371.    Image.Framecount.width  = c2d(reverse(substr(codehead,6,2)))
  372.    Image.Framecount.height = c2d(reverse(substr(codehead,8,2)))
  373.  
  374.    if Image.framecount.left~=0 | Image.framecount.top~=0 | Image.framecount.width~=width | Image.framecount.height~=Height then
  375.    do
  376.       FullFrameFlag = 0
  377.    end
  378.  
  379.    stuff = c2b(right(codehead,1))
  380.    localcolor = left(stuff,1)
  381.    interlace = substr(stuff,2,1)
  382.  
  383.    localsortflag = substr(stuff,3,1)
  384.    localcolortable = c2d(b2c(right(stuff,3)))+1
  385.  
  386.    if localcolor=1 then 
  387.    do
  388.       Image.FrameCount.LCT = getCT(localcolortable)
  389.    end
  390.  
  391.    call seek('in',1)
  392.    chsz = c2d(readch('in',1))
  393.  
  394.    do while chsz>0
  395.       call seek('in',chsz)
  396.       chsz = c2d(readch('in',1))
  397.    end
  398.  
  399.    /* end of image */
  400.    Image.framecount.end = seek('in',0)
  401. end
  402. 'requestnotify' '"Gif is incomplete.  May be a problem with final image"'
  403. framecount=framecount-1
  404. return
  405.  
  406. /***************************/
  407. SaveFrame:
  408. /*
  409. ** read the appropriate data out of the gif and
  410. ** construct a new gif, save to T:, load new gif, and delete temp gif
  411. */
  412.  
  413. Parse Arg SaveFrame
  414. call seek('in',image.SaveFrame.Start,'B')
  415. Data = readch('in',Image.SaveFrame.end-Image.SaveFrame.Start)
  416.  
  417. tempGCT = GCT
  418. if image.saveframe.transflag=1 & Accuracy=1 then
  419. do
  420.    origTrans = Pickcolor(image.saveframe.transcolor gct)
  421.    if Image.saveframe.lct~="" then
  422.    do
  423.       if CheckTransparent(image.saveframe.transcolor image.saveframe.lct)>=0 then
  424.       do
  425.          tempLCT = replacetransparent(image.saveframe.transcolor image.saveframe.lct)
  426.          data = overlay(templct,data,11)
  427.       end
  428.    end
  429.    else
  430.    do
  431.       if CheckTransparent(image.saveframe.transcolor gct)>=0 then
  432.       do
  433.          tempgct = replacetransparent(image.saveframe.transcolor gct)
  434.       end
  435.    end
  436. end
  437.  
  438. if ~open('out',TempDir||Temp'.gif','w') then
  439. do
  440.    'RequestNotify' 'Unable to open Temporary File, exiting...'
  441.    call quit()
  442. end
  443.  
  444. call writech('out',header||tempGCT||data||'3b'x)
  445. call close('out')
  446.  
  447. return
  448.  
  449. /***************************/
  450. SkipBlocks:
  451. /*
  452. ** There are some gif extension codes here
  453. ** The only one we're interested in is the "Graphic Control Extension"
  454. ** because that will tell us how to work with delta frames and
  455. ** the transparent color of such frames
  456. */
  457.  
  458. bltype = readch('in',1)
  459. len = c2d(readch('in',1))
  460.  
  461. select
  462.    when bltype = 'F9'x then
  463.    do
  464.       extdata = readch('in',len)
  465.       stuff = c2b(left(extdata,1))
  466. /* 
  467. ** TransFlag is either 1 for transparent color, or 0 for no transparent color
  468. ** Transcolor is # from 0-255 which is index of the transparent color
  469. ** Disposal method is the way the frame is dealt with after use
  470. ** I may not have a use for it.
  471. */
  472.  
  473.       Image.framecount.TransFlag  = right(stuff,1)
  474.       if Image.Framecount.TransFlag=1 then
  475.       do
  476.          TranspFlag=1
  477.       end
  478.       Image.framecount.transcolor = c2d(right(extdata,1))
  479.       Image.framecount.disposal   =   c2d(b2c(substr(stuff,4,3)))
  480.    end
  481.    when bltype = 'FF'x then 
  482.    do
  483.       call seek('in',len) /* skipApplication Extension type */
  484.       BlkLen = c2d(readch('in',1)) /* read length of extension type */
  485.       call seek('in',blklen) /* skip Application Extension data */
  486.    end
  487.    otherwise
  488.    do
  489.       call seek('in',len) /* read in other extension data */
  490.    end
  491. end
  492.  
  493. ending = readch('in',1)
  494. if ending~='00'x then return(0)
  495.  
  496. return(1)
  497.  
  498. /***************************/
  499. pickcolor: Procedure
  500.  
  501. /*
  502. ** Input: Index number, color table
  503. **    picks the index color number out of the color table
  504. */
  505.  
  506.  
  507. parse arg index ' ' table
  508. temp = (substr(table,(index)*3+1,3))
  509. return(c2d(left(temp,1))' 'c2d(substr(temp,2,1))' 'c2d(right(temp,1)))
  510.  
  511. /***************************/
  512. ReplaceTransparent: procedure
  513.  
  514. /*
  515. ** This procedure will replace a duplicated transparent color in a palette
  516. ** with a different color.  It does this by getting a completely random color
  517. ** to replace it with, since the odds of getting a random duplicate are small 
  518. ** (256 out of 16 million :^)
  519. */
  520. parse arg index ' ' table
  521. call randu(time('s'))
  522. done = '0'
  523.  
  524. do while done>=0
  525.    rgb = d2c(random(0,255))||d2c(random(0,255))||d2c(random(0,255))
  526.    table = overlay(rgb,table,(index)*3+1,3)
  527.    done = checktransparent(index table)
  528. end
  529. return(table)   
  530.  
  531. /***************************/
  532. CheckTransparent: procedure
  533.  
  534. /*
  535. ** This procedure checks to make sure that the transparent color
  536. ** isn't repeated elsewhere within the palette.  Since Gifs are colormapped
  537. ** it's possible to have the same color transparent, and not transparent, and
  538. ** since IFX works in 24 bit, it would be unable to tell the difference between the 
  539. ** two.
  540. */
  541. parse arg index ' ' table
  542.  
  543. color = pickcolor(index table)
  544.  
  545. do count=0 to length(table)/3-1
  546.    if count~=index then
  547.    do
  548.       temp = pickcolor(count table)
  549.       if temp=color then return(count)
  550.    end
  551. end
  552.  
  553. return(-1)
  554. /***************************/
  555. RequestFrame:
  556.  
  557. if PreviousFrame>framecount then
  558. do
  559.    PreviousFrame=Framecount
  560. end
  561. 'requestslider "Load which Frame" 1' framecount PreviousFrame
  562. if rc>0 then
  563. do
  564.    call quit()
  565. end
  566. return(result)
  567. /***************************/
  568.  
  569. CreateTranspBrush:
  570.  
  571. parse arg tranbrush
  572. ColorTable=tempGCT
  573. if Image.count.LCT~="" then
  574. do
  575.    ColorTable=Image.count.LCT
  576. end            
  577. 'swap'
  578. 'LoadBuffer' '"'tranbrush'"' 
  579. TranColor = PickColor(Image.Count.TransColor colortable)
  580. /*Trancolor = c2d(left(trancolor,1))  c2d(substr(trancolor,2,1)) c2d(right(trancolor,1))*/
  581. 'activecolor'
  582. actpal = result
  583. 'GetPalette' '-1'
  584. oldpal = result
  585. 'setpalette' actpal tranColor
  586. 'getrange 1'
  587. oldrang = result
  588. 'setrange 1' actpal actpal
  589. 'transparency exclude 1 closeness 1'
  590. OldTran = result
  591. 'getmain'
  592. parse var result '"' . '"' wid hei .
  593. 'scissors'
  594. 'box 0 0' wid hei
  595. 'setrange 1' oldrang
  596. 'setpalette' actpal oldpal
  597. 'transparency' oldtran
  598. 'swap'
  599. return
  600.  
  601. /***************************/
  602. DoDisposal:
  603.  
  604. /*
  605. ** Disposal methods
  606. **    0 : No disposal specified.  The decoder is not required 
  607. ** to take any action.
  608. **    1 : Do Not dispose.  The graphic is to be left in place.
  609. **    2 : Restore to background color.  The area used by the 
  610. ** graphic must be restored to the background color.
  611. **    3 : Restore to previous.  The decoder is required to restore
  612. ** the area overwritten by the graphic with what was there prior
  613. ** to rendering the graphic
  614. **    4-7 : undefined (shouldn't happen?)
  615. */
  616.  
  617. select
  618.    when Image.count.Disposal<2 | Image.count.Disposal>3 then
  619.    do
  620.       'brushhandle' 0 0
  621.       'point' image.count.left   image.count.top
  622.    end
  623.  
  624.    when image.count.Disposal=3 & (count=ReqFrame | Bustanim=1) then
  625.    do
  626.       'brushhandle' 0 0
  627.       'point' image.count.left   image.count.top 
  628.    end
  629.  
  630.    when Image.count.Disposal=2 & (count=ReqFrame | bustanim=1) then
  631.    do
  632.       'brushhandle' 0 0
  633.       'point' image.count.left   image.count.top
  634.    end
  635.    otherwise nop
  636. end
  637.  
  638. return
  639.  
  640. /***************************/
  641. UndoDisposal:
  642.  
  643. if image.count.Disposal=2 then
  644. do
  645.    'activecolor'
  646.    actpal = result
  647.    'GetPalette' '-1'
  648.    oldpal = result
  649.    /*bg = Pickcolor(backgrd GCT)*/
  650.  
  651.    'setpalette' actpal OrigTrans
  652.    'filledbox' image.count.left image.count.top image.count.width image.count.height
  653.    'setpalette' actpal oldpal
  654. end
  655. else if image.count.disposal=3 & BustAnim=1 then
  656. do
  657.    'UNDO'
  658. end
  659.  
  660. return
  661.  
  662. /***************************/
  663.  
  664. CreateImage:
  665. /* 
  666. ** First frame, just load it
  667. */
  668. if count=1 then
  669. do
  670.    if image.count.transflag=1 then
  671.    do
  672.       ColorTable=GCT
  673.       if Image.count.LCT~="" then
  674.       do
  675.          ColorTable=Image.count.LCT
  676.       end            
  677.       TranColor = PickColor(Image.Count.TransColor colortable)
  678.       OrigTrans = TranColor
  679.    end
  680.    if Backgroundflag~=1 then
  681.    do
  682.       'LoadBuffer' '"'filename'"'  
  683.    end
  684.    else
  685.    do
  686.       'CreateBuffer force' width height pickcolor(image.count.transcolor GCT)
  687.       if Image.count.transflag=1 then
  688.       do
  689.          tempgct = gct
  690.          call CreateTranspBrush(filename)
  691.       end
  692.       else
  693.       do
  694.          'LoadBrush' '"'filename'"'
  695.       end
  696.       Call DoDisposal()
  697.    end
  698. end   
  699. else
  700. do
  701.    
  702.    call SaveFrame(Count)
  703.  
  704. /*
  705. ** Image has transparent color
  706. */
  707.    if Image.count.transflag=1 & Accuracy=1 then
  708.    do
  709.       call CreateTranspBrush(Tempdir||Temp'.gif')
  710.    end
  711.    else
  712.    do
  713.       'LoadBrush' '"'TempDir||Temp'.gif"'
  714.    end
  715.    call delete(Tempdir||Temp'.gif')
  716.          
  717.    Call DoDisposal()
  718. end
  719.  
  720. if BustAnim=1 then
  721. do
  722.    Call SaveImage()
  723. end
  724. if Accuracy=1 & count~=ReqFrame then
  725. do
  726.    call UndoDisposal()
  727. end
  728. return
  729.  
  730. /***************************/
  731. SaveImage:
  732.  
  733. 'SAVEBUFFERAS' 'ILBM' savepath || savefile || right(count,length(framecount),'0') || '.rgb'
  734. return
  735.  
  736. /***************************/
  737. GetPath: Procedure
  738.  
  739. parse arg path
  740.  
  741. return(left(path,max(pos(':',path),lastpos('/',path))))
  742. /***************************/
  743. GetFile: Procedure
  744.  
  745. parse arg path
  746. return(delstr(path,1,max(pos(':',path),lastpos('/',path))))
  747.  
  748.  
  749. /***************************/
  750.  
  751. CheckBackground:
  752.  
  753. right = image.1.left+image.1.width
  754. bottom = image.1.top + image.1.height
  755.  
  756. do count = 2 to framecount
  757.    if (image.count.left + image.count.width)>right | (image.count.top + image.count.height)>bottom then return(1)
  758. end
  759. return(0)
  760.  
  761. /***************************/
  762. quit:
  763.  
  764. call close('in')
  765. 'unlockgui'
  766. 'unlockinput'
  767. call setclip('GIFLoaderPrevName',filename)
  768. call setClip('GIFLoaderPrevFrame',ReqFrame)
  769. call setclip('GIFSaveDir',SavePath)
  770. 'killbrush'
  771. 'redraw'
  772. exit